package com.xijia.aop.service.impl;

import com.xijia.aop.ext.ExtAsync;
import com.xijia.aop.service.MemberService;
import com.xijia.aop.utils.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 1、MemberServiceImpl 只要继承了接口(implements MemberService )，那么 @RestController 注解和 @Async 注解就不能同时存在, （jdk动态代理的bug）
 * 2、在 MemberServiceImpl 实现类中, 直接使用this 调用异步 @Async 将不生效, 因为this直接调用当前类，没有经过代理对象, 创建异步是在代理时执行的，所有this不会进行异步操作
 * 3、在 MemberServiceImpl 实现类中, 使用@Async， 直接获取当前类的代理对象, 使用代理对象调用带有 @Async 注解的方法就ok了
 * 4、在 MemberServiceImpl 实现类中, 使用@Async， 或者把 @Async异常操作方法单独建立一个类, 就能避免this调用了，不经过代理对象了(如: aop)
 * @author wangsong
 * @mail 1720696548@qq.com
 * @date 2020/8/30 0030 21:16
 * @version 1.0.0
 */
@RestController
@Slf4j
public class MemberServiceImpl  implements MemberService {

    // 方法二: 使用新的类来处理异步操作
    @Autowired
    private MemberServiceImplAsync memberServiceImplAsync;

    @Override
    @GetMapping("/addUser")
    public String addUser() {
        log.info(">>>流程1");

        // 方法一： 先获得代理对象,在通过代理对象调用本类的 addUserLog方法
         MemberServiceImpl proxy = SpringUtils.getBean("memberServiceImpl");
         proxy.addUserLog();

        // 方法二: 使用新的类来处理异步操作
        // memberServiceImplAsync.addUserLog();

        // 直接调用调用无效不会被动态代理，@Async注解自然也无效, 因为开启异步是在动态代理中开启的
        //this.addUserLog();

        log.info(">>>流程3");
        return "success";
    }

    /**
     * 异步方法
     * @return
     */
    @ExtAsync // 自定义
    //@Async  // 该注解不能和@RestController 或 @Controller 同时存在
    public void addUserLog() {
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
        }
        log.info(">>>流程2");
    }
}
